{-# OPTIONS -Wall #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  Lirio.Lyrics
-- Copyright   :  (c) Stephen Tetley 2012
-- License     :  BSD3
--
-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>
-- Stability   :  highly unstable
-- Portability :  GHC
--
-- Lyrics - @lyricmode@ with absolute duration and @lyricsto@ 
-- with automatic alignment (TODO).
--
--------------------------------------------------------------------------------


module Lirio.Lyrics
  (
  
    AbsLyrics
  , abslyrics
  , syllable
  , syllables



  ) where

import qualified Lirio.Base.AbsDuration as AD
import Lirio.Base.Duration
import Lirio.Base.Overloading
import Lirio.Score hiding ( text )

import Text.PrettyPrint.Leijen hiding ( dot )   -- package: wl-pprint

import Control.Applicative hiding ( empty )
import Data.Monoid hiding ( (<>) )

-- | Use with @lyricmode@ ...
--
newtype AbsLyrics a = AbsLyrics { getAbsLyrics :: AD.DAbsolute () a }



instance Functor AbsLyrics where
  fmap f = AbsLyrics . fmap f . getAbsLyrics


instance Applicative AbsLyrics where
  pure a    = AbsLyrics $ pure a
  mf <*> ma = AbsLyrics $ getAbsLyrics mf <*> getAbsLyrics ma


instance Monad AbsLyrics where
  return   = pure
  ma >>= k = AbsLyrics $ getAbsLyrics ma >>= (getAbsLyrics . k) 



instance Monoid a => Monoid (AbsLyrics a) where
  mempty          = pure mempty
  ma `mappend` mb = AbsLyrics $ getAbsLyrics ma `mappend` getAbsLyrics mb





-- | Run the AbsLyrics
--
abslyrics :: AbsLyrics a -> Score a
abslyrics ma = withScore $ \_ -> 
    let (a,_,w) = AD.runNotelist () (getAbsLyrics ma) in (a, w)


-- Could use NoteM (note) where Pch is String...

syllable :: String -> Duration -> AbsLyrics ()
syllable ss d = AbsLyrics $ genericEvent (text ss) d


syllables :: [(String,Duration)] -> AbsLyrics ()
syllables = mapM_ (uncurry syllable)